import VisionCamera
import ARKit

@objc(ARCoreSwiftPlugin)
public class ARCoreSwiftPlugin: NSObject {
    private var session: ARSession?
    private var isSessionInitialized = false
    
    @objc public override init() {
        super.init()
    }
    
    @objc public func initializeSession() {
        // 初始化ARSession
        session = ARSession()
        
        // 配置ARSession
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = [.horizontal]
        configuration.isLightEstimationEnabled = true
        
        session?.run(configuration, options: [.resetTracking, .removeExistingAnchors])
        isSessionInitialized = true
        
        print("ARKit session initialized successfully")
    }
    
    @objc public func callback(_ frame: Frame, withArguments arguments: [String: Any]?) -> Any {
        // 检查ARSession是否存在
        guard let session = self.session else {
            print("ARKit session not initialized")
            return ["error": "ARKit session not initialized"]
        }
        
        // 检查会话是否已初始化
        guard isSessionInitialized else {
            print("ARKit session not configured")
            return ["error": "ARKit session not configured"]
        }
        
        // 在iOS中，我们通过检查currentFrame来判断会话是否准备就绪
        // 如果currentFrame为nil，说明会话还未准备好
        guard let currentFrame = session.currentFrame else {
            print("ARKit session not ready - no current frame")
            // 等待几帧后再返回错误
            return ["error": "ARKit session not ready", "retry": true]
        }
        
        // 获取相机姿态信息
        let camera = currentFrame.camera
        let transform = camera.transform
        
        // 提取位置信息 (translation)
        let tx = Float(transform.columns.3.x)
        let ty = Float(transform.columns.3.y)
        let tz = Float(transform.columns.3.z)
        
        // 提取旋转信息 (rotation)
        let qx = Float(transform.columns.0.x)
        let qy = Float(transform.columns.1.y)
        let qz = Float(transform.columns.2.z)
        let qw = Float(transform.columns.3.w)
        
        // 执行hitTest获取屏幕中心点到平面的距离
        let centerPoint = CGPoint(x: Double(frame.width) / 2.0, y: Double(frame.height) / 2.0)
        let hitTestResults = currentFrame.hitTest(centerPoint, types: .existingPlaneUsingExtent)
        
        var result: [String: Any] = [
            "tx": tx,
            "ty": ty,
            "tz": tz,
            "qx": qx,
            "qy": qy,
            "qz": qz,
            "qw": qw
        ]
        
        // 如果有hitTest结果，添加距离信息
        if let closestResult = hitTestResults.first {
            let hitDistance = Float(closestResult.distance)
            result["hitDistance"] = hitDistance
        }
        
        // 处理两点间距离的计算（如果提供了参数）
        if let point1X = arguments?["point1X"] as? NSNumber,
           let point1Y = arguments?["point1Y"] as? NSNumber,
           let point2X = arguments?["point2X"] as? NSNumber,
           let point2Y = arguments?["point2Y"] as? NSNumber {
            
            let point1 = CGPoint(x: CGFloat(point1X.floatValue), y: CGFloat(point1Y.floatValue))
            let point2 = CGPoint(x: CGFloat(point2X.floatValue), y: CGFloat(point2Y.floatValue))
            
            // 对两个点执行hitTest
            let point1Results = currentFrame.hitTest(point1, types: .existingPlaneUsingExtent)
            let point2Results = currentFrame.hitTest(point2, types: .existingPlaneUsingExtent)
            
            // 如果两个点都有hitTest结果，计算它们之间的距离
            if let result1 = point1Results.first, let result2 = point2Results.first {
                let position1 = result1.worldTransform.columns.3
                let position2 = result2.worldTransform.columns.3
                
                // 计算两点间距离
                let dx = Float(position2.x - position1.x)
                let dy = Float(position2.y - position1.y)
                let dz = Float(position2.z - position1.z)
                let pointsDistance = sqrt(dx*dx + dy*dy + dz*dz)
                
                result["pointsDistance"] = pointsDistance
            }
        }
        
        return result
    }
}